/*
 * @Author       : wang chao
 * @Date         : 2023-02-16 11:05:29
 * @LastEditors: wangchao
 * @LastEditTime: 2024-10-12 14:44:09
 * @FilePath: \JD-RTT-Driver\applications\u_data.c
 * @Description  :
 * Copyright 2023 BingShan, All Rights Reserved.
 */
#include "u_data.h"
#include "u_app.h"
#include "u_soc.h"
#include "u_utilits.h"

#define DBG_TAG "DATA"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

/**
 *******************************************************************************
 *                               存储操作接口函数
 *******************************************************************************
 */
extern uint8_t e2rm_storage_word(uint16_t location, int16_t word);
extern int16_t e2rm_load_word(uint16_t location);

extern AI_Param ADC1_AIS[8];
extern AI_Param ADC2_AIS[8];
extern AI_Param ADC3_AIS[8];

void get_sensor_range(void)
{
    for (rt_uint8_t i = 0; i < 8; i++)
    {
        ADC1_AIS[i].phy_max = 0;
        ADC1_AIS[i].phy_min = 0;
        ADC2_AIS[i].phy_max = 0;
        ADC2_AIS[i].phy_min = 0;
        ADC3_AIS[i].phy_max = 0;
        ADC3_AIS[i].phy_min = 0;
    }
    // ====== ADC1 ======
    // -->>放电电流
    ADC1_AIS[3].phy_max = 1500 * 10;
    ADC1_AIS[3].phy_min = 0;
    // -->>充电电流
    ADC1_AIS[0].phy_max = 1500 * 10;
    ADC1_AIS[0].phy_min = 0;
    // -->>温度预留
    ADC1_AIS[1].phy_max = 0;
    ADC1_AIS[1].phy_min = 0;
    // -->>电解液温度
    ADC1_AIS[2].phy_max = 80 * 10;
    ADC1_AIS[2].phy_min = 0;
    // ====== ADC2 ======
    // -->>2#正极泵出口压力（kPa * 100）
    ADC2_AIS[3].phy_max = 350 * 10;
    ADC2_AIS[3].phy_min = 0;
    // -->>1#正极泵出口压力（kPa * 100）
    ADC2_AIS[0].phy_max = 350 * 10;
    ADC2_AIS[0].phy_min = 0;
    // -->>BMS柜内湿度
    ADC2_AIS[1].phy_max = 100 * 10;
    ADC2_AIS[1].phy_min = 0;
    // -->>BMS柜内温度
    ADC2_AIS[2].phy_max = 125 * 10;
    ADC2_AIS[2].phy_min = -400;
    // ====== ADC3 ======
    // -->>负极罐压力
    ADC3_AIS[2].phy_max = 3000;
    ADC3_AIS[2].phy_min = -3000;
    // -->>正极罐压力
    ADC3_AIS[1].phy_max = 3000;
    ADC3_AIS[1].phy_min = -3000;
    // -->>B侧负极泵出口压力（kPa * 100）
    ADC3_AIS[0].phy_max = 350 * 10;
    ADC3_AIS[0].phy_min = 0;
    // -->>1#负极泵出口压力（kPa * 100）
    ADC3_AIS[3].phy_max = 350 * 10;
    ADC3_AIS[3].phy_min = 0;
}

rt_bool_t get_adc_calibrate_parameters(void)
{
    rt_uint8_t index;

    // ADC-01
    for (index = 0; index < 8; index++)
    {
        ADC1_AIS[index].vol_min = 4;
        ADC1_AIS[index].vol_max = 20;
    }
    for (index = 0; index < 8; index++)
    {
        ADC1_AIS[index].vol_gain = e2rm_load_word(ADC0_CALI_GAIN_BASE_ADDR + index * 4);
        rt_thread_mdelay(10);
    }
    for (index = 0; index < 8; index++)
    {
        ADC1_AIS[index].vol_offset = e2rm_load_word(ADC0_CALI_OFFSET_BASE_ADDR + index * 4);
        rt_thread_mdelay(10);
    }
    // ADC-02
    for (index = 0; index < 8; index++)
    {
        ADC2_AIS[index].vol_min = 4;
        ADC2_AIS[index].vol_max = 20;
    }
    for (index = 0; index < 8; index++)
    {
        ADC2_AIS[index].vol_gain = e2rm_load_word(ADC1_CALI_GAIN_BASE_ADDR + index * 4);
        rt_thread_mdelay(10);
    }
    for (index = 0; index < 8; index++)
    {
        ADC2_AIS[index].vol_offset = e2rm_load_word(ADC1_CALI_OFFSET_BASE_ADDR + index * 4);
        rt_thread_mdelay(10);
    }
    // ADC-03
    for (index = 0; index < 8; index++)
    {
        ADC3_AIS[index].vol_min = 4;
        ADC3_AIS[index].vol_max = 20;
    }
    for (index = 0; index < 8; index++)
    {
        ADC3_AIS[index].vol_gain = e2rm_load_word(ADC2_CALI_GAIN_BASE_ADDR + index * 4);
        rt_thread_mdelay(10);
    }
    for (index = 0; index < 8; index++)
    {
        ADC3_AIS[index].vol_offset = e2rm_load_word(ADC2_CALI_OFFSET_BASE_ADDR + index * 4);
        rt_thread_mdelay(10);
    }
    return RT_TRUE;
}

/**
 * 适配湖北大力-BMS系统
 */
//
rt_uint16_t SYSTEM_WORK_STATE_WORD1 = 0;
rt_uint16_t SYSTEM_WORK_STATE_WORD2 = 0;
rt_uint16_t SYSTEM_WORK_STATE_WORD3 = 0;
rt_uint16_t SYSTEM_WORK_STATE_WORD4 = 0;
//
rt_uint16_t SYSTEM_FAULT_ACTION = 0x00;
//

total_power_data power_data = {.group_a_total_volt = 0, .group_b_total_volt = 0, .sys_total_current = 0, .sys_total_power = 0, .sys_total_volt = 0};

extern rt_uint16_t get_a_side_volt(rt_uint8_t chx);
extern rt_uint16_t get_b_side_volt(rt_uint8_t chx);

// Define a struct to hold SOC data and count
typedef struct
{
    rt_uint16_t data[10];  // Array for SOC data
    rt_uint16_t count;     // Count to track the index
} SOC_Data;

// Create instances for group A and group B SOC data
static SOC_Data soc_a = {{0}, 0};
static SOC_Data soc_b = {{0}, 0};

void calculate_power_data(void)
{
    rt_uint8_t index = 0;
    rt_uint16_t stack_volt[6] = {0};

    // Get total voltages
    power_data.group_a_total_volt = get_a_side_volt(0);
    power_data.group_b_total_volt = get_b_side_volt(0);

    // Calculate system total voltage
    power_data.sys_total_volt = power_data.group_a_total_volt + power_data.group_b_total_volt;

    for (index = 0; index < 6; index++)
    {
        stack_volt[index] = get_a_side_volt(index + 1);
    }
    power_data.group_a_avr_volt = median_filter_average_value(stack_volt, 6, 1);

    for (index = 0; index < 6; index++)
    {
        stack_volt[index] = get_b_side_volt(index + 1);
    }
    power_data.group_b_avr_volt = median_filter_average_value(stack_volt, 6, 1);

    // Get total current from sensor data
    power_data.sys_total_current = 0;

    // Calculate system total power in integer form
    rt_uint32_t iv = power_data.sys_total_volt;                   // iv scaled as voltage (x100)
    rt_uint32_t ii = power_data.sys_total_current;                // ii scaled as current (x10)
    power_data.sys_total_power = (rt_int16_t)((iv * ii) / 1000);  // Result in KW

    // Update SOC for group A
    rt_uint16_t soc = get_bms_soc(1);
    soc_a.data[soc_a.count++] = soc;
    if (soc_a.count == 10)
    {
        soc_a.count = 0;
        power_data.group_a_soc = median_filter_average_value(soc_a.data, 10, 2);
    }

    // Update SOC for group B
    soc = get_bms_soc(2);
    soc_b.data[soc_b.count++] = soc;
    if (soc_b.count == 10)
    {
        soc_b.count = 0;
        power_data.group_b_soc = median_filter_average_value(soc_b.data, 10, 2);
    }
}
